#!/usr/bin/python
#-*- coding:utf-8 -*-

import os
import sys
import redisco
import random
import json
import datetime
import time
import sys
import uuid
import codecs

class TaskDB:
    key_tasks_list = "bcs:indexs:all"
    key_tasks_act = "bcs:indexs:act"
    key_tasks_ready = "bcs:indexs:rdy"
    key_tasks_down = "bcs:indexs:dwn"
    key_tasks_err = "bcs:indexs:err"
    key_tasks = "bcs:tasks:%s"
    key_tasks_config = "bcs:configs"

    def __init__(self,host="localhost",port=6379,db=0):
        redisco.connection_setup(host=host, port=port, db=db)
        self.client = redisco.get_client()
        self.updown_data = {
            "up_total":1,
            "up_currect":0,
            "up_progress":0.0,
            "down_total":1,
            "down_currect":0,
            "down_progress":0.0
        }

    def gen_id(self):
        return str(uuid.uuid1())

    def clear_db(self):
        self.client.flushdb()

    def get_tasks_count(self):
        return self.client.llen(self.key_tasks_list)

    def get_tasks_indexs(self):
        tc = self.get_tasks_count()
        if tc > 0:
            return self.client.lrange(self.key_tasks_list,0,tc-1)
        else:
            return None

    def exists_task(self,task_id):
        return self.client.exists(self.key_tasks%(task_id))

    def get_task(self,task_id):
        if self.exists_task(task_id):
            return self.client.hgetall(self.key_tasks%(task_id))
        else:
            return None

    def get_task_status(self,task_id):
        if self.exists_task(task_id):
            if self.client.hexists(self.key_tasks%(task_id),"task_stat"):
                return self.client.hget(self.key_tasks%(task_id),"task_stat")
        return None

    def get_tasks(self):
        tis= self.get_tasks_indexs()
        if tis != None :
            tasks = []
            for tid in tis:
                t = self.get_task(tid)
                if t != None:
                    tasks += t
            return tasks
        else:
            return []

    def add_task(self,task):
        tid = self.gen_id()
        while self.exists_task(tid):
            tid = self.gen_id()
        task["tid"]=tid
        task["task_stat"]="ready"
        self.client.hmset(self.key_tasks%(tid),task)
        self.client.rpush(self.key_tasks_list,tid)
        self.client.rpush(self.key_tasks_ready,tid)
        return task

    def update_task(self,task_id,task):
        t = self.get_task(task_id)
        if t != None:
            #print task
            #print t
            for k,v in task.items():
                #print k,v
                if k!="tid":
                    t[k]=v
            self.client.hmset(self.key_tasks%(task_id),t)
            return t
        else:
            return None

    def change_stat(self, task_id, stat):
        if stat in ["ready","act","down","err"]:
            _stat = self.get_task_status(task_id)
            #print _stat
            if _stat != stat:
                if _stat == "ready":
                    self.client.lrem(self.key_tasks_ready,task_id)
                elif _stat == "act":
                    self.client.lrem(self.key_tasks_act,task_id)
                elif _stat == "down":
                    self.client.lrem(self.key_tasks_down,task_id)
                elif _stat == "err":
                    self.client.lrem(self.key_tasks_err,task_id)
                if stat == "ready":
                    self.client.rpush(self.key_tasks_ready,task_id)
                elif stat == "act":
                    self.client.rpush(self.key_tasks_act,task_id)
                elif stat == "down":
                    self.client.rpush(self.key_tasks_down,task_id)
                elif stat == "err":
                    self.client.rpush(self.key_tasks_err,task_id)
                self.client.hmset(self.key_tasks%(task_id),{"task_stat":stat})
            return True
        return False

    def delete_task(self,task_id):
        if self.exists_task(task_id):
            stat = self.get_task_status(task_id)
            self.client.lrem(self.key_tasks_list,task_id)
            if stat == "ready":
                self.client.lrem(self.key_tasks_ready,task_id)
            elif stat == "act":
                self.client.lrem(self.key_tasks_act,task_id)
            elif stat == "down":
                self.client.lrem(self.key_tasks_down,task_id)
            elif stat == "err":
                self.client.lrem(self.key_tasks_err,task_id)
            self.client.delete(self.key_tasks%(task_id))
            return True
        else:
            return False

    def set_updown_progress(self,up_mode,task_id,v):
        self.change_stat(task_id,"act")
        t=0
        if (up_mode):
            t = self.updown_data["up_total"]
            self.update_task(task_id,{"up_currect":v,"up_progress":(v/t)*100})
        else:
            t = self.updown_data["down_total"]
            self.update_task(task_id,{"down_currect":v,"down_progress":(v/t)*100})
        #print str((v/t)*100),

    def set_updownload_begin(self,up_mode,task_id,v):
        self.change_stat(task_id,"ready")
        if (up_mode):
            self.updown_data["up_total"] = v
            self.update_task(task_id,{"up_total":v})
        else:
            self.updown_data["down_total"] = v
            self.update_task(task_id,{"down_progress":v})

    def set_updownload_finish(self,up_mode,task_id):
        self.change_stat(task_id,"down")
        if (up_mode):
            t = self.updown_data["up_total"]
            self.update_task(task_id,{"up_currect":t,"up_progress":100.0})
        else:
            t = self.updown_data["down_total"]
            self.update_task(task_id,{"down_currect":t,"down_progress":100.0})

    def set_updownload_err(self,up_mode,task_id,err):
        self.change_stat(task_id,"err")
        if (up_mode):
            self.update_task(task_id,{"err_id":"0xFF01","err_info":"upload err","error":err})
        else:
            self.update_task(task_id,{"err_id":"0xFF02","err_info":"download err","error":err})

    def get_config(self,key):
        if key != None and key.strip() != "":
            if self.client.exists(self.key_tasks_config):
                if self.client.hexists(self.key_tasks_config,key):
                    return self.client.hget(self.key_tasks_config,key)
        return ""

    def set_config(self,key,value):
        if key != None and key.strip() != "":
            self.client.hset(self.key_tasks_config,{key.strip(),value})

db = TaskDB()

def valid_login(username,passwd):
    return True

def log_the_user_in(user):
    return ""

def get_redis_tasks():
    return db.get_tasks()

def get_redis_taskinfo(task_id):
    return db.get_task(task_id)

def create_redis_task(task):
    return db.add_task(task)

def update_task(task_id,task):
    return db.update_task(task_id,task)

def remove_task(task_id):
    return db.delete_task(task_id)